package com.example.demo.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

/**
 * @author Fa
 * @description DemoServiceImpl
 * @date 2020/10/15 0015 下午 04:21
 */
@Service
public class DemoServiceImpl implements DemoService {

    @Autowired
    private UserRepository userRepository;

    private static ThreadPoolExecutor calcExecutor;
    private static ThreadPoolExecutor middleExecutor;
    private static ThreadPoolExecutor ioExecutor;

    static {
        init();
    }

    public static void init() {
        calcExecutor = ThreadUtil.newExecutorByBlockingCoefficient(0.1F);
        middleExecutor = ThreadUtil.newExecutorByBlockingCoefficient(0.5F);
        ioExecutor = ThreadUtil.newExecutorByBlockingCoefficient(0.9F);
    }


    @Override
    public String insertTestData(Integer startName, Integer userSize) {
        insertUserData(startName, userSize);
        return "success";
    }


    /**
     * 插入用户数据
     *
     * @param startName 开始name(int类型)
     * @param userSize  用户个数
     */
    public void insertUserData(Integer startName, Integer userSize) {
//        int pageSize = 500;
//        CountDownLatch countDownLatch = ThreadUtil.newCountDownLatch((int) Math.ceil(userSize / (double) pageSize));
        CountDownLatch countDownLatch = ThreadUtil.newCountDownLatch(userSize - 1);

        long startMillis = System.currentTimeMillis();
        int end = userSize + startName;

        HashMap<String, AtomicInteger> hashMap = new HashMap<>();

        final List<User>[] customersList = new List[]{new ArrayList<>()};
        AtomicInteger atomicInteger = new AtomicInteger(0);
        IntStream.range(startName, end).forEach(name -> {
            customersList[0].add(genCustomers(String.valueOf(name)));
//            if (customersList[0].size() % pageSize == 0) {
//                List<User> newCustomersList = customersList[0];

            ioExecutor.execute(() -> {
//                    ThreadUtil.safeSleep(RandomUtil.randomLong(100, pageSize));
//                    ThreadUtil.safeSleep(RandomUtil.randomLong(1, 3));
//                    userRepository.saveAll(newCustomersList);
                countDownLatch.countDown();
                String threadName = Thread.currentThread().getName();
                if (!hashMap.containsKey(threadName)) {
                    hashMap.put(threadName, new AtomicInteger(1));
                } else {
                    AtomicInteger atomicInt = hashMap.get(threadName);
                    atomicInt.incrementAndGet();
                }
                System.out.println(atomicInteger.incrementAndGet());
            });

//                customersList[0] = new ArrayList<>();
//            } else if (name == end - 1) {
//                List<User> newCustomersList = customersList[0];

//                ioExecutor.execute(() -> {
////                    ThreadUtil.safeSleep(RandomUtil.randomLong(100, pageSize));
//                    ThreadUtil.safeSleep(RandomUtil.randomLong(3, 9));
////                    userRepository.saveAll(newCustomersList);
//                    countDownLatch.countDown();
//                });

//                customersList[0] = new ArrayList<>();
//            }

        });
        ThreadUtil.execute(() -> {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(hashMap);
            System.out.println("耗时Millis: " + (System.currentTimeMillis() - startMillis));
        });
    }


    /**
     * 生成用户
     */
    private User genCustomers(String name) {
        User user = new User();
        user.setName(name);
        user.setUrl(RandomUtil.randomString(9));
        return user;
    }


}
